/**
 * 
 */
package etf.db40;

import java.util.Random;

import etf.library.Address;
import etf.library.IndexedAddress;

import com.db4o.ObjectSet;
import com.db4o.query.Query;

/**
 * Class for testing insert, delete, update and lookup of a simple object using
 * object oriented database db40
 * 
 * @author Nermin Softic
 */
public class SimpleDb4o extends Db4oUtil{
	
	final static String DB4OFILENAME = "/SimpleTest.db4o";
	//private static Runtime _runtime = Runtime.getRuntime();

	//public static ObjectContainer db;
	
	public SimpleDb4o(){
		createDatabase(DB4OFILENAME);
	}
	public SimpleDb4o(String fileName){
		createDatabase("/" + fileName + ".db40");
	}
	/*
	 * Funkcija koja generise zadani broj slogova i iste
	 * insertuje u bazu podataka
	 */
	public long insert(int brojSlogova) {
		long elapsedTime = 0;
		try {
			long startTime = System.currentTimeMillis();
			for (int i = 0; i < brojSlogova; i++) {
				Address address = new Address("Splitska" + i,i, "Sarajevo", 71000, "BiH");
				db.store(address);
			}
			db.commit();
			long stopTime = System.currentTimeMillis();
			elapsedTime = stopTime - startTime;
		} catch (Exception e) {
			e.printStackTrace();
			db.close();
		}
		
		return elapsedTime;
	}
	/*
	 * Funkcija koja generise i insertuje zadani broj slogova
	 * sa 2 indeksiranja polja
	 */
	public long indexedInsert(int brojSlogova) {
		long elapsedTime = 0;
		try {
			long startTime = System.currentTimeMillis();
			for (int i = 0; i < brojSlogova; i++) {
				IndexedAddress address = new IndexedAddress("Splitska_" + i,i, "Sarajevo", 71000, "BiH");
				db.store(address);
			}
			db.commit();
			long stopTime = System.currentTimeMillis();
			elapsedTime = stopTime - startTime;
		} catch (Exception e) {
			e.printStackTrace();
			db.close();
		}
		
		return elapsedTime;
	}
	 /*
	  * Funkcija koja brise zadani broj slogova
	  * Generisati slucajnu sekvencu brojeva koji predstavlju id
	  * ili neko drugo unique polje a zatim izbrisati date objekte
	  * Koriste se SODA upiti
     */
	public long delete(int size) {
		long elapsedTime = 0;
		try {
			long startTime = System.currentTimeMillis();
			Address address = new Address();
			address.setHouseNumber(getRandom(size));
			ObjectSet<Address> result = db.queryByExample(address);
			if (result.hasNext()) {
				db.delete(result.next());
			}
			db.commit();
			long stopTime = System.currentTimeMillis();
			elapsedTime = stopTime - startTime;
		} catch (Exception e) {
			e.printStackTrace();
			db.close();
		}
		return elapsedTime;
	}
	
	/*
	 * Brisanje preko indeksiranog polja
	 */
	public long indexedDelete(int size) {
		long elapsedTime = 0;
		try {
			long startTime = System.currentTimeMillis();
			IndexedAddress address = new IndexedAddress();
			address.setHouseNumber(getRandom(size));
			ObjectSet<IndexedAddress> result = db.queryByExample(address);
			if (result.hasNext()) {
				db.delete(result.next());
			}
			db.commit();
			long stopTime = System.currentTimeMillis();
			elapsedTime = stopTime - startTime;
		} catch (Exception e) {
			e.printStackTrace();
			db.close();
		}
		return elapsedTime;
	}
    /*
     *  Funkcija koja brise sve elemente jedne jednostavne klase
     *  Koristi se QBE mehanizam
     */
	public long deleteAll(Object o){
		long elapsedTime = 0;
		try {
			long startTime = System.currentTimeMillis();
			deleteSpecific(o);
			db.commit();
			long stopTime = System.currentTimeMillis();
			elapsedTime = stopTime - startTime;
		} catch (Exception e) {
			e.printStackTrace();
			db.close();
		}
		return elapsedTime;	
	}
	
	
	public long query(int size){
		long elapsedTime = 0;
		try {
			long startTime = System.currentTimeMillis();
			
			Address address = new Address();
			address.setHouseNumber(getRandom(size));
			ObjectSet<Address> result = db.queryByExample(address);
			if(result.hasNext()){
				Address  a = (Address) result.next();
				System.out.println(a.getStreet());
			}
			long stopTime = System.currentTimeMillis();
			elapsedTime = stopTime - startTime;
		} catch (Exception e) {
			e.printStackTrace();
			db.close();
		}
		return elapsedTime;
	}
	
	public long indexedQueryInt(int size){
		long elapsedTime = 0;
		try {
			long startTime = System.currentTimeMillis();
			IndexedAddress address = new IndexedAddress();
			address.setHouseNumber(getRandom(size));
			ObjectSet<IndexedAddress> result = db.queryByExample(address);
			
			if(result.hasNext()){
				IndexedAddress  a = (IndexedAddress) result.next();
				System.out.println(a.getStreet());
			}
		
			long stopTime = System.currentTimeMillis();
			elapsedTime = stopTime - startTime;
		} catch (Exception e) {
			e.printStackTrace();
			db.close();
		}
		return elapsedTime;
	}
	
	public long indexedQueryString(int size){
		long elapsedTime = 0;
		try {
			long startTime = System.currentTimeMillis();
			IndexedAddress address = new IndexedAddress();
			address.setStreet("Splitska_"+getRandom(size));
			ObjectSet<IndexedAddress> result = db.queryByExample(address);
			
			if(result.hasNext()){
				IndexedAddress  a = (IndexedAddress) result.next();
				System.out.println(a.getStreet());
				
			}
		
			long stopTime = System.currentTimeMillis();
			elapsedTime = stopTime - startTime;
		} catch (Exception e) {
			e.printStackTrace();
			db.close();
		}
		return elapsedTime;
	}
	
	public long update(int size){
		long elapsedTime = 0;
		try {
			long startTime = System.currentTimeMillis();
			IndexedAddress address = new IndexedAddress();
			address.setHouseNumber(getRandom(size));
			ObjectSet<IndexedAddress> result = db.queryByExample(address);
			if(result.hasNext()){
				IndexedAddress  a = (IndexedAddress) result.next();
				a.setCity("New_city");
				db.store(a);
				db.commit();
			}
		
			long stopTime = System.currentTimeMillis();
			elapsedTime = stopTime - startTime;
		} catch (Exception e) {
			e.printStackTrace();
			db.close();
		}
		return elapsedTime;
	}
	
	private int getRandom(int max){
		Random r = new Random();
        return r.nextInt(max); 
	}
}
